import java.util.LinkedList;

public class Comparador {

	public String compararBasesDeDatos(DataBase bd1,DataBase bd2){
		String difTablasUno = "\n\n****Tablas exclusivas de '"+bd1.getNombre() +"'\n\n";
		String difTablasDos = "\n\n****Tablas exclusivas de '"+bd2.getNombre()+"'\n\n";

		String dif = diferenciasTablas(bd1.getTables(),bd2.getTables());
		if(dif.length() != 0)
			difTablasUno = difTablasUno + dif + "\n";
		else
			difTablasUno = "";

		dif = diferenciasTablas(bd2.getTables(),bd1.getTables());
		if(dif.length() != 0)
			difTablasDos = difTablasDos + dif + "\n";
		else
			difTablasDos = "";

		return difTablasUno + difTablasDos;
	}

	private String diferenciasTablas(LinkedList<Tabla> t1, LinkedList<Tabla> t2){
		String res = "";
		int i = 0;
		int j = 0;
		boolean b;

		while(i < t1.size()){
			b = false;
			while(j < t2.size()){
				if(t1.get(i).getNombre().compareTo(t2.get(j).getNombre())==0){
					b = true;
					break;
				}
				j++;
			}

			if(b)
				res = res + compararTablas(t1.get(i),t2.get(j)) + "\n";
			else
				res = res + "TABLA : " +t1.get(i).getNombre() + " \n";

			j = 0;
			i++;
		}

		return res;
	}

	private String compararTablas(Tabla tabla1,Tabla tabla2){
		String res = "TABLA : " + tabla1.getNombre();
		String difColumnasTabla = "\n\tCOLUMNAS EXCLUSIVAS \n\n\t\t";
		String difPrimaryTabla = "\n\tDIFERENCIAS POR PRIMARY KEY \n\n\t\t";
		String difTipoTabla = "\n\tDIFERENCIAS POR TIPOS \n\n\t\t";
		String difForeignKey = "\n\tDIFERENCIAS POR FOREIGN KEY \n\n\t\t";
		int n = 0;
		int m = 0;
		boolean b;

		LinkedList<Columna> colt1 = tabla1.getColumnas();
		LinkedList<Columna> colt2 = tabla2.getColumnas();
		Columna col1,col2;

		while(n < colt1.size()){
			m = 0;
			col1 = colt1.get(n);
			colt2 = tabla2.getColumnas();
			b = false;
			while(m < colt2.size()){
				col2 = colt2.get(m);
				if(col1.getNombre().compareTo(col2.getNombre())==0){
					b = true;
					if(col1.isPrimaryKey() == col2.isPrimaryKey()){
						if(col1.getTipo() != col2.getTipo())
							difTipoTabla = difTipoTabla + col1.getNombre() + ": " + TipoSQL.tipoDato(col1.getTipo()) + "\n\t\t";
					}
					else
						difPrimaryTabla = difPrimaryTabla + col1.getNombre() + "\n\t\t";
				}
				m++;
			}
			if(!b)
				difColumnasTabla = difColumnasTabla + col1.getNombre() + "\n\t\t";
			n++;
		}
		
		difForeignKey = difForeignKey + compararClavesForaneas(tabla1, tabla2);
		
		if(difForeignKey.length() == 34)
			difForeignKey = "";

		if(difColumnasTabla.length() == 26)
			difColumnasTabla = "";
		
		if(difPrimaryTabla.length() == 34)
			difPrimaryTabla = ""; 

		if(difTipoTabla.length() == 28)
			difTipoTabla = "";

		if((difPrimaryTabla.length() == 0) && (difTipoTabla.length() == 0) && (difColumnasTabla.length() == 0) && difForeignKey.length() == 0)
			res = "";

		return res + difForeignKey + difColumnasTabla + difPrimaryTabla + difTipoTabla + "\n";
	}

	public String compararProcedimientos(DataBase bd1,DataBase bd2){
		String difProceUno = "****Diferencia de Procedimientos entre (1)'"+bd1.getNombre() +" ' y (2)'"+bd2.getNombre()+"'\n\n";
		String difProceDos = "\n\n****Diferencia de Procedimientos entre (1)'"+bd2.getNombre() +" ' y (2)'"+bd1.getNombre()+"'\n\n";

		String dif = diferenciasProcedimientos(bd1.getProcedures(),bd2.getProcedures());
		if(dif.length() != 0)
			difProceUno = difProceUno + dif + "\n";
		else
			difProceUno = "";

		dif = diferenciasProcedimientos(bd2.getProcedures(),bd1.getProcedures());
		if(dif.length() != 0)
			difProceDos = difProceDos + dif + "\n";
		else
			difProceDos = "";


		return difProceUno + difProceDos;
	}

	private String diferenciasProcedimientos(LinkedList<Procedure> procUno,LinkedList<Procedure> procDos){
		String iguales = "\tProcedures con distinto perfil\n";
		String distintos = "\n\tProcedures exlusivos de (1)\n";
		int i = 0;
		int j = 0;
		boolean b;

		while(i < procUno.size()){
			b = false;
			while(j < procDos.size()){
				if(procUno.get(i).getNombre().compareTo(procDos.get(j).getNombre())==0){
					b = true;
					break;
				}
				j++;
			}

			if(b)
				iguales = iguales +"\t\t" +compararProcedimientos(procUno.get(i),procDos.get(j)) + "\n";
			else
				distintos = distintos  + "\n\t\t\tPROCEDIMIENTO : " +procUno.get(i).getNombre() + "\n";

			j = 0;
			i++;
		}
		
		if(iguales.length() == 32)
			iguales = "";
		if(distintos.length() == 30)
			distintos = "";
		
		return iguales + distintos;
	}

	private String compararProcedimientos(Procedure p1,Procedure p2){
		String res = "\n\t\t\tPROCEDIMIENTO " + p1.getNombre() + "\n";
		String perfil1 = p1.getPerfil();
		String perfil2 = p2.getPerfil();

		if(perfil1.compareTo(perfil2) != 0)
			res = res + "\n\t\t\t\t(1)" + perfil1 + "\n\t\t\t\t(2)" + perfil2;
		else
			res = "";

		return res;
	}

	public String diferenciaTriggers(DataBase bd1,DataBase bd2){
		String difTrigUno = "****Diferencia de Triggers de (1)'"+bd1.getNombre() + "' y (2)'"+bd2.getNombre()+"'\n";
		String difTrigDos = "\n\n****Diferencia de Triggers entre (1)'"+bd2.getNombre() +" ' y (2)'"+bd1.getNombre()+"'\n\n";

		String dif = compararTriggers(bd1.getTriggers(),bd2.getTriggers());
		if(dif.length() != 0)
			difTrigUno = difTrigUno + dif + "\n";
		else
			difTrigUno = "";

		dif = compararTriggers(bd2.getTriggers(),bd1.getTriggers());
		if(dif.length() != 0)
			difTrigDos = difTrigDos + dif + "\n";
		else
			difTrigDos = "";


		return difTrigUno + difTrigDos;
	}

	public String compararTriggers(LinkedList<Trigger> t1,LinkedList<Trigger> t2){
		String res = "";

		int i = 0;
		int j = 0;
		boolean b;

		while(i < t1.size()){
			b = false;
			while(j < t2.size()){
				if(t1.get(i).getNombre().compareTo(t2.get(j).getNombre())==0){
					b = true;
					break;
				}
				j++;
			}

			if(b)
				res = res + compararTriggers(t1.get(i),t2.get(j)) + "\n";
			else
				res = res + "\nTRIGGER : " +t1.get(i).getNombre() + "\n";

			j = 0;
			i++;
		}

		return res;
	}

	private String compararTriggers(Trigger t1,Trigger t2){
		String res = "\nTRIGGER " + t1.getNombre() + "\n";
		String perfil1 = t1.getPerfil();
		String perfil2 = t2.getPerfil();

		if(perfil1.compareTo(perfil2) != 0)
			res = res + "\n\t(1)" + perfil1 + "\n\t(2)" + perfil2;
		else
			res = "";

		return res;
	}

	public String compararClavesForaneas(Tabla tabla1, Tabla tabla2){
		String exclusivasDBuno = "";
		String exclusivasDBdos = "";
		String excl = "";

		excl = exclusivas(tabla1.getClavesForeaneas(),tabla2.getClavesForeaneas());
		if(excl.length() != 0)
			exclusivasDBuno = exclusivasDBuno + excl;
		else
			exclusivasDBuno = "";

		excl = exclusivas(tabla2.getClavesForeaneas(),tabla2.getClavesForeaneas());
		if(excl.length() != 0)
			exclusivasDBdos = exclusivasDBdos + excl;
		else
			exclusivasDBdos = "";

		return exclusivasDBuno + exclusivasDBdos;
	}

	private String exclusivas(LinkedList<ClaveForanea> tabladb1, LinkedList<ClaveForanea> tabladb2){
		String res = "";
		int i = 0;

		while(i < tabladb1.size()){
			ClaveForanea cf = tabladb1.get(i);
			if(!tabladb2.contains(cf))
				res = res + "\t" + cf.getPerfil() + "\n";
			i++;
		}

		return res;
	}
}